package com.jwsoft.manager.business.integration.demo.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.business.integration.demo.DemoIntegration;
import com.jwsoft.manager.common.enums.demo.DemoDictEnum;
import com.jwsoft.manager.common.vo.demo.DemoTestDetailVO;
import com.jwsoft.manager.common.vo.demo.DemoTestVO;
import com.jwsoft.manager.dao.model.DemoTest;
import com.jwsoft.manager.dao.service.DemoTestService;
import com.xiaoyy.core.common.enums.BoolEnum;
import com.xiaoyy.core.common.enums.FuncTypeEnum;
import com.xiaoyy.core.common.exception.AppException;
import com.xiaoyy.core.config.annotations.ApiService;
import com.xiaoyy.core.config.annotations.OpApi;
import com.xiaoyy.core.config.annotations.SaveOplog;
import com.xiaoyy.core.config.store.SessionHelper;
import com.xiaoyy.core.config.util.PagerUtil;
import com.xiaoyy.core.dict.utils.DictUtil;
import com.xiaoyy.sso.common.enums.RoleDictEnum;
import com.xiaoyy.sso.common.vo.role.RoleVO;
import com.xiaoyy.sso.dao.model.SysRole;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 例子接口管理
 * **/

@Service
@ApiService(funcCode = "DEMO", title = "接口例子")
public class DemoIntegrationImpl implements DemoIntegration {
    @Autowired
    DemoTestService demoTestService;
    @Autowired
    DictUtil dictUtil;
    @Override
    @OpApi(funcCode = "DEMO0001",title = "分页查询例子权限控制例子",funcType = FuncTypeEnum.query)
    public PageInfo<DemoTestVO> getList(DemoTestVO demoTestVO) {
        //使用mybatis-plus 生成查询语句
        QueryWrapper<DemoTest> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda().select(DemoTest::getDemoId,DemoTest::getName,DemoTest::getSex)//设置查询结果的字段，不设置为select *
                .eq(DemoTest::getDel, BoolEnum.FALSE.getType());//where条件 = 相当于 del='0' 如果表字段中包含del逻辑删除标志，所有查询条件都要加上
        if (StringUtils.isNotBlank(demoTestVO.getName())){
            // 根据条件拼查询语句
            queryWrapper.lambda().like(DemoTest::getName,demoTestVO.getName());// like 查询 相当与 like '%xxx%'
        }

        // 还有其他使用方式请自行百度参考mybatis plus

        //开启分页
        if (demoTestVO.getPageNum() != null && demoTestVO.getPageSize() != null) {
            PageHelper.startPage(demoTestVO.getPageNum(),demoTestVO.getPageSize());
        }
        List<DemoTest> demoTestList = demoTestService.list(queryWrapper);
        if (CollectionUtils.isEmpty(demoTestList)){
            //判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(demoTestVO.getPageNum(),demoTestVO.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<DemoTest> pageInfo = new PageInfo<>(demoTestList);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<DemoTestVO> list = Convert.toList(DemoTestVO.class, pageInfo.getList());
        //转义数据字典值
        dictUtil.valueToName(list, Arrays.asList(DemoDictEnum.values()));
        return PagerUtil.parsePagerVo(list, pageInfo);
    }

    @Override
    @OpApi(funcCode = "DEMO0002",title = "单个查询例子，不需要校验权限",funcType = FuncTypeEnum.query,checkPrivilege = BoolEnum.FALSE)
    public DemoTestVO getDetail(DemoTestDetailVO vo) {
        //根据主键查询数据
        DemoTest demoTest = demoTestService.getById(vo.getDemoId());
        if (demoTest==null){
            throw new AppException("未找到数据");
        }
        // 如果表结构中有逻辑删除标志，必须加上该判断
        if (BoolEnum.TRUE.getType().equals(demoTest.getDel())){
            throw new AppException("该数据已被删除");
        }
        // 返回参数需要通过common层的vo实体类，用该方法可以单个实体转换
        DemoTestVO demoTestVO = Convert.convert(DemoTestVO.class,demoTest);
        //转义数据字典值
        dictUtil.valueToName(demoTestVO, Arrays.asList(DemoDictEnum.values()));
        return demoTestVO;
    }
    /**
     * 操作日志中 dataType 需要传入业务所属类型的标识字段，比如人员相关业务都会有人员id，该值就传人员id，
     * 比如单位业务，一般都有单位id字段，该值就传单位id，操作日志回退需要校验是否同类型业务，
     * 比如同人员业务，有后续业务是不能回退的。
     * */
    @Override
    @OpApi(funcCode = "DEMO0003",title = "保存并且记录操作日志例子",funcType = FuncTypeEnum.edit)
    @SaveOplog(operationType = "DEMO0003",operationName = "测试保存业务",dataType = "demoId")
    public DemoTestVO save(DemoTestVO vo) {
        // 获取登录操作用户所有信息 SessionHelper.getSessionInfo()
        // 操作用户信息用SessionHelper 类获取，必须有@OpApi 才能使用，不然获取到为空
        // 只要在最开始的方法中添加就可以了，后续调用的方法不用再次添加也能获取到。
        String userId= SessionHelper.getUserId();
        //校验数据字典值是否在范围内
        dictUtil.validValue(vo,Arrays.asList(DemoDictEnum.values()));
        // 生成保存的实体，
        DemoTest demoTest = Convert.convert(DemoTest.class,vo);
        // 新增或更新，如果主键不存在则新增，主键存在的更新
        demoTestService.saveOrUpdate(demoTest);
        // 获取新增后的表数据主键
        vo.setDemoId(demoTest.getDemoId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "DEMO0004",title = "删除例子",funcType = FuncTypeEnum.edit)
    @SaveOplog(operationType = "DEMO0004",operationName = "测试删除例子",dataType = "demoId")
    public void del(DemoTestDetailVO vo) {
        demoTestService.removeById(vo.getDemoId());
        //批量删除 传入主键列表
        //demoTestService.removeByIds(list);
    }

    @Override
    @OpApi(funcCode = "DEMO0005",title = "修改例子",funcType = FuncTypeEnum.edit)
    @SaveOplog(operationType = "DEMO0005",operationName = "修改例子",dataType = "demoId")
    public DemoTestVO update(DemoTestVO vo) {
        //根据主键查询数据
        DemoTest old = demoTestService.getById(vo.getDemoId());
        if (old==null){
            throw new AppException("未找到数据");
        }
        // 如果表结构中有逻辑删除标志，必须加上该判断
        if (BoolEnum.TRUE.getType().equals(old.getDel())){
            throw new AppException("该数据已被删除");
        }
        DemoTest newData = Convert.convert(DemoTest.class,old);
        //相同字段拷贝数据方法
        BeanUtil.copyProperties(vo,newData);
        demoTestService.updateById(newData);
        return vo;

    }

    @Override
    @OpApi(funcCode = "DEMO0006",title = "批量保存不支持单个回退例子",funcType = FuncTypeEnum.insert)
    @SaveOplog(operationType = "DEMO0006",operationName = "批量保存不支持单个回退例子",dataType = "batch")
    @Transactional
    public void saveBatch(List<DemoTestVO> voList) {
        List<DemoTest> list = Convert.toList(DemoTest.class,voList);
        demoTestService.saveBatch(list);
        //批量保存或更新
        //demoTestService.saveOrUpdateBatch(list);
    }
}
